using CfgTable;
using IQIGame.Onigao.Framework;
using System;

namespace IQIGame.Onigao.Logic
{
    public class LevelNormalBuff : BaseLevelBuff
    {
        public CfgLevelBuff cfg { get; private set; }
        public override int cid => cfg.Id;
        public override int durationFrame => cfg.Duration <= 0 ? -1 : LgLevelConvertUtil.MillisecToFrame(cfg.Duration);
        public override int triggerInterval => cfg.TriggerInverval <= 0 ? -1 : LgLevelConvertUtil.MillisecToFrame(cfg.TriggerInverval);
        public float speedRatio => cfg.SpeedRatio <= 0 ? 1 : (float)cfg.SpeedRatio / 100;
        public override int maxStack => cfg.MaxStack;

        private ServiceManager _serviceMgr;
        private int _lastTriggerFrame;
        private int _triggeredCount;

        public void Init(BaseLevelFunctionHost host, CfgLevelBuff cfg)
        {
            _host = host;
            this.cfg = cfg;
            if (cfg.Service != null && cfg.Service.Count > 0)
            {
                _serviceMgr = ClassPool.Get<ServiceManager>();
                _serviceMgr.SetHost(_host);
                _serviceMgr.Refresh(cfg.Service);
            }
        }

        public void SetData(int stack, float leftSec)
        {
            this.stack = stack;
            int leftFrame = (int)Math.Round(leftSec * LgLevelConst.FrameRate);
            this._startFrame = _host.region.level.levelFrame + leftFrame - durationFrame;
        }

        public override void OnAdd()
        {
            base.OnAdd();
#if UNITY_EDITOR
            LogicLog.Log($"添加buff，{GetDebugInfo()}");
#endif
            _lastTriggerFrame = _startFrame;
            if ((LevelBuffTriggerType)cfg.TriggerType == LevelBuffTriggerType.Add)
            {
                TryTriggerService();
            }
        }

        public override void OnRemove()
        {
            base.OnRemove();
#if UNITY_EDITOR
            LogicLog.Log($"移除buff，{GetDebugInfo()}");
#endif
            if ((LevelBuffTriggerType)cfg.TriggerType == LevelBuffTriggerType.Remove)
            {
                TryTriggerService();
            }
        }

        protected override void OnAddStack(int addValue, bool isManualModify)
        {
            base.OnAddStack(addValue, isManualModify);
#if UNITY_EDITOR
            LogicLog.Log($"堆叠buff，{GetDebugInfo()}");
#endif
            if (addValue > 0)
            {
                _startFrame = _host.region.level.levelFrame;
                if (!isManualModify && (LevelBuffTriggerType)cfg.TriggerType == LevelBuffTriggerType.Add)
                {
                    TryTriggerService();
                }
            }
        }

        protected override void OnUpdateIntervalTrigger()
        {
            if ((LevelBuffTriggerType)cfg.TriggerType == LevelBuffTriggerType.Interval && triggerInterval > 0)
            {
                Level level = _host.region.level;
                if (level.levelFrame - _lastTriggerFrame >= triggerInterval)
                {
                    _lastTriggerFrame = level.levelFrame;

                    TryTriggerService();
                }
            }
        }

        public override bool TryTriggerService(ServiceTriggerType triggerType = ServiceTriggerType.None)
        {
            if (_serviceMgr == null)
                return false;
            LevelPlayer player = null;
            if (_host is LevelPlayer)
            {
                player = _host as LevelPlayer;
            }
            else if (_host is LevelHero)
            {
                player = (_host as LevelHero).player;
            }
            (bool isOK, int _) = ConditionLevelLogicUtil.Check(cfg.TriggerCondition, _host.region, player, _host as LevelEntity);
            if (isOK)
            {
                bool countOK = cfg.TriggerMaxNumber < 0 || _triggeredCount < cfg.TriggerMaxNumber;
                bool probabilityOK = cfg.TriggerProbability >= 100 || _host.region.level.random.randomInt(100) + 1 <= cfg.TriggerProbability;
                bool triggered = false;
                if (countOK && probabilityOK)
                {
                    triggered = _serviceMgr.TryTrigger(null, triggerType);
                    if (triggered)
                    {
                        _triggeredCount++;
                    }
                }
                if (cfg.TriggerMaxNumber >= 0 && _triggeredCount >= cfg.TriggerMaxNumber)
                {
                    isExpired = true;
                }
                return triggered;
            }
            return false;
        }

        public override void OnReset()
        {
            base.OnReset();
            cfg = null;
            if (_serviceMgr != null)
            {
                ClassPool.Put(_serviceMgr);
                _serviceMgr = null;
            }
            _lastTriggerFrame = 0;
            _triggeredCount = 0;
        }
    }
}
